﻿/*----------------------------------------------------------------
    // Copyright (C) 2009 江苏华招网
    // 版权所有。 
    // 作者：李刚 
    //
    // 文件名：BasePage.cs
    // 文件功能描述：页面基类，处理系统页面权限
    // 创建标识：李刚 2009-03-17
    //
    // 修改标识：李刚 2009-03-18
    // 修改描述：在基类中处理权限控件的验证，不再向控件提供public方法
    //
    // 修改标识：李刚 2009-03-20
    // 修改描述：基类中对页面内EnableRBAC属性为False的控件不再注入验证事件，以减小服务器性能消耗
    //
    // 审核人：
    // 审核时间：
    // 审核说明：
 //----------------------------------------------------------------*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using HZ.Web;
using System.IO;
using HZ.Supervise.Model.Enum;
using HZ.Supervise;


public class BasePage : System.Web.UI.Page
{
    #region 私有成员
    /// <summary>
    /// 私有变量 页面所属的模块代码
    /// </summary>
    private string _ModuleNo = string.Empty;
    /// <summary>
    /// 进入页面需要的操作类型  默认的操作： OperateType.查看
    /// </summary>
    private string _OperateType = HZ.Supervise.Model.Enum.OperateType.查看.ToString();
    /// <summary>
    /// 返回页面
    /// </summary>
    private string _ReturnUrl = string.Empty;
    /// <summary>
    /// 序列化的查询条件
    /// </summary>
    private string _QueryCondition = "";
    #endregion

    /// <summary>
    /// 构造函数
    /// </summary>
    public BasePage()
    {
        this.Load += new EventHandler(BasePage_Load);
        this.LoadComplete += new EventHandler(BasePage_LoadComplete);
    }

    /// <summary>
    /// 重载OnLoad 给带权限控件的Validate事件绑定验证方法
    /// </summary>
    /// <param name="e"></param>
    protected override void OnLoad(EventArgs e)
    {
        //将页面中所有继承IRbacControl的控件注册验证事件
        BindrbacValidateEvent(this.Page);
        base.OnLoad(e);
    }

    /// <summary>
    /// 重载OnPreRender 给带权限控件的 PreRender事件绑定验证方法
    /// </summary>
    /// <param name="e"></param>
    protected override void OnPreRender(EventArgs e)
    {
        ////将页面中所有继承IRbacControl的控件注册呈现事件
        BindrbacPreRenderEvent(this.Page);
        base.OnPreRender(e);
    }

    /// <summary>
    /// 重写ProcessRequest
    /// </summary>
    /// <param name="context"></param>
    public override void ProcessRequest(HttpContext context)
    {
        //从浏览器重输入的URl 不做返回处理
        if (context.Request.UrlReferrer != null && context.Request[Constants.QUERYSTRING_RETURN_URL] == null)
        {
            //从菜单页面来 无需记录returnUrl
            if (context.Request.UrlReferrer.AbsolutePath.IndexOf("Default") != -1 || context.Request.UrlReferrer.AbsolutePath.EndsWith("/"))
            {
                base.ProcessRequest(context);
            }
            //两次停留在同一页面 则不做返回处理
            else if (context.Request.UrlReferrer.AbsolutePath != context.Request.Url.AbsolutePath)
            {
                //去掉多余的returnUrl参数
                int index = context.Request.UrlReferrer.PathAndQuery.IndexOf(Constants.QUERYSTRING_RETURN_URL);
                string returnUrl = "";
                if (index != -1)
                {
                    //去掉多余的returnUrl参数
                    returnUrl = Constants.QUERYSTRING_RETURN_URL + "=" + HttpUtility.UrlEncode(context.Request.UrlReferrer.PathAndQuery.Substring(0, index - 1));
                }
                else
                {
                    returnUrl = Constants.QUERYSTRING_RETURN_URL + "=" + HttpUtility.UrlEncode(context.Request.UrlReferrer.PathAndQuery);
                }
                //当前页面无参数的要使用 "?" 追加 returnRrl
                if (context.Request.Url.Query != "")
                {
                    context.Response.Redirect(context.Request.Url.PathAndQuery + "&" + returnUrl);
                }
                else
                {
                    context.Response.Redirect(context.Request.Url.PathAndQuery + "?" + returnUrl);
                }
            }
            else
            {
                base.ProcessRequest(context);
            }
        }
        else
        {
            base.ProcessRequest(context);
        }
    }

    /// <summary>
    /// 重写render 将页面中脚本替换成 defer 使得js懒加载
    /// </summary>
    /// <param name="writer"></param>
    protected override void Render(HtmlTextWriter writer)
    {
        //string oldContent;
        //string newContent;
        //StringWriter stringWriter = new StringWriter();
        //HtmlTextWriter oldwriter = new HtmlTextWriter(stringWriter);
        //base.Render(oldwriter);

        //oldContent = stringWriter.ToString();
        //newContent = oldContent.Replace("type=\"text/javascript\">", "type=\"text/javascript\" defer>");
        //writer.Write(newContent);
        base.Render(writer);

    }

    #region 事件

    /// <summary>
    /// load事件处理，先于aspx页面Page_Load执行
    /// </summary>
    private void BasePage_Load(object sender, EventArgs e)
    {
        //检查页面执行权限
        CheckAuthority();
        //设置returnurl
        GetReturnUrl();
        //获取查询条件
        GetQueryCondition();
    }

    /// <summary>
    /// loadComplete事件处理
    /// </summary>
    private void BasePage_LoadComplete(object sender, EventArgs e)
    {
        //待实现...
    }

    /// <summary>
    /// 控件的PreRender事件处理 决定控件的呈现
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void control_PreRender(object sender, EventArgs e)
    {
        IRbacControl rbacCtrl = (IRbacControl)sender;
        WebControl control = (WebControl)sender;

        //根据控件所进行的操作 动态设定其呈现状态
        if (rbacCtrl.AttributeToControl == "Enabled")
        {
            control.Enabled = control.Enabled && ValidateRight(rbacCtrl);
        }
        else
        {
            control.Visible = control.Visible && ValidateRight(rbacCtrl);
        }

    }

    /// <summary>
    /// 控件的Validate事件处理 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void rbacCtrl_Validate(object sender, EventArgs e)
    {
        IRbacControl rbacCtrl = (IRbacControl)sender;

        if (!ValidateRight(rbacCtrl))
        {
            //取消控件动作
            rbacCtrl.ActionCancel = true;
            //跳转到无权访问页面
            Page_NoPermission();
        }
        else
        {
            //记录控件操作日志
            this.ControlOperateLog(rbacCtrl);
        }
    }

    #endregion

    #region 私有方法

    /// <summary>
    /// 检查页面执行权限
    /// </summary>
    private void CheckAuthority()
    {
        if (!ValidateSession())
        {
            //跳转到登陆页面
            Page_NoLogin();
        }
        if (!ValidatePageRight(this._ModuleNo))
        {

            //跳转到无权访问页面
            Page_NoPermission();
        }

    }

    /// <summary>
    /// 递归寻找控件 并注册验证事件 （验证事件在 click事件之前发生）
    /// </summary>
    /// <param name="ctrl"></param>
    /// <param name="strCommandName"></param>
    private void BindrbacValidateEvent(Control parent)
    {
        foreach (Control control in parent.Controls)
        {
            if (control.HasControls())
            {
                BindrbacValidateEvent(control);
            }
            else if (control is IRbacControl)
            {
                //将页面中继承IRbacControl的控件且启用权限控制的控件 注入验证事件
                IRbacControl rbacCtrl = (IRbacControl)control;
                if (rbacCtrl.EnableRBAC)
                {
                    rbacCtrl.Validate += new EventHandler(rbacCtrl_Validate);
                }
            }
        }
    }

    /// <summary>
    /// 递归寻找控件 并注册控件呈现事件
    /// </summary>
    /// <param name="parent"></param>
    private void BindrbacPreRenderEvent(Control parent)
    {
        foreach (Control control in parent.Controls)
        {
            if (control.HasControls())
            {
                BindrbacPreRenderEvent(control);
            }
            else if (control is IRbacControl)
            {
                //将页面中继承IRbacControl的控件且启用权限控制的控件 注入验证事件
                IRbacControl rbacCtrl = (IRbacControl)control;
                if (rbacCtrl.EnableRBAC)
                {
                    control.PreRender += new EventHandler(control_PreRender);
                }
            }
        }
    }

    /// <summary>
    /// 验证控件操作权限
    /// </summary>
    /// <returns></returns>
    private bool ValidateRight(IRbacControl rbacCtrl)
    {
        Control control = (Control)rbacCtrl;
        //如果控件的模块号为空 则集成页面的模块号
        if (rbacCtrl.ModuleNo == string.Empty)
        {
            rbacCtrl.ModuleNo = ((BasePage)control.Page).ModuleNo;
        }

        bool isHaveRight = true;
        if (rbacCtrl.EnableRBAC)
        {
            if (rbacCtrl.ModuleNo != "" && rbacCtrl.OperateType != "")
            {
                isHaveRight = ValidateModuleRight(rbacCtrl.ModuleNo, rbacCtrl.OperateType);
            }
        }
        return isHaveRight;
    }

    /// <summary>
    /// 设置returnUrl
    /// </summary>
    private void GetReturnUrl()
    {
        if (HttpContext.Current.Request.QueryString[Constants.QUERYSTRING_RETURN_URL] != null)
        {
            int index = HttpContext.Current.Request.QueryString[Constants.QUERYSTRING_RETURN_URL].IndexOf(",");
            if (index == -1)
            {
                this._ReturnUrl = HttpContext.Current.Request.QueryString[Constants.QUERYSTRING_RETURN_URL];

            }
            else
            {
                this._ReturnUrl = HttpContext.Current.Request.QueryString[Constants.QUERYSTRING_RETURN_URL].Substring(0, index);
            }
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public string SetQueryCondition<T>(T obj)
    {
        this._QueryCondition = StringUtility.Compress(StringUtility.ConvertObjectToString(obj));
        return HttpUtility.UrlEncode(this._QueryCondition);

        //StringWriter sw = new StringWriter();
        //(new LosFormatter()).Serialize(sw, obj);
        //string hashkey = HZ.Fun.GetMd5(sw.ToString());
        //Session[hashkey] = obj;
        //return hashkey;

    }

    private void GetQueryCondition()
    {
        if (HttpContext.Current.Request.QueryString[Constants.QUERYSTRING_QUERY_CONDITION] != null)
        {
            string hashkey = HttpContext.Current.Request.QueryString[Constants.QUERYSTRING_QUERY_CONDITION];
            this._QueryCondition = hashkey;
        }
    }

    //记录控件操作日志
    private void ControlOperateLog(IRbacControl rbacCtrl)
    {
        Control control = (Control)rbacCtrl;
        //如果控件的模块号为空 则集成页面的模块号
        if (rbacCtrl.ModuleNo == string.Empty)
        {
            rbacCtrl.ModuleNo = ((BasePage)control.Page).ModuleNo;
        }

        //记录日志
        //模块为空不记录
        if (rbacCtrl.ModuleNo != "" && rbacCtrl.OperateType != "")
        {
            OperateLog(rbacCtrl.ModuleNo.ToString(), rbacCtrl.OperateType.ToString());
        }

    }

    /// <summary>
    /// 记录页面日志
    /// </summary>
    private void PageOperateLog()
    {
        //记录日志
        //模块为空 或者查看操作不记录
        if (this.ModuleNo != "" && this.PageOperateType != OperateType.查看.ToString())
        {
            OperateLog(this.ModuleNo.ToString(), this.PageOperateType.ToString());
        }
    }

    #endregion

    #region 业务逻辑接口 可修改部分

    /// <summary>
    /// 页面级权限判断
    /// </summary>
    /// <param name="strModuleName"></param>
    /// <returns></returns>
    private bool ValidatePageRight(string strModuleNo)
    {
        bool isHaveRight = true;
        if (strModuleNo != "")
        {
            isHaveRight = ValidateModuleRight(strModuleNo, this._OperateType);
        }
        return isHaveRight;
    }

    /// <summary>
    /// 操作级权限判断
    /// </summary>
    /// <param name="strModuleNo"></param>
    /// <param name="strOperateType"></param>
    /// <returns></returns>
    private bool ValidateModuleRight(string strModuleNo, string strOperateType)
    {
        HZ.Supervise.IBLL.IBLL_User userCtrl = BLLFactory.BLL_User();
        string userId = CurrentAccount.GetUser().UserID;

        //超级管理员拥有一切权限
        if (CurrentAccount.IsSuperAdmin())
        {
            return true;
        }
        else
        {
            //访问权限验证业务逻辑...
            return userCtrl.CheckUserRule(userId, EnumParse.GetModule(strModuleNo).Value, EnumParse.GetOperateType(strOperateType).Value);
        }
        
    }

    /// <summary>
    /// 检查用户Session是否正常
    /// </summary>
    /// <returns></returns>
    private bool ValidateSession()
    {
        if (CurrentAccount.IsTimeout())
        {
            return false;
        }
        return true;
    }

    /// <summary>
    /// 操作无权
    /// </summary>
    private void Page_NoPermission()
    {
        CurrentAccount.Goto_NoPermission();
    }

    /// <summary>
    /// 未登陆
    /// </summary>
    private void Page_NoLogin()
    {
        CurrentAccount.Goto_Login();
    }

    /// <summary>
    /// 记录系统操作日志
    /// </summary>
    /// <param name="strModuleNo"></param>
    /// <param name="strOperateType"></param>
    private void OperateLog(string strModuleNo, string strOperateType)
    {
        //
        try
        {
            //HZ.Supervise.Model.KeyOperationLog log = new HZ.Supervise.Model.KeyOperationLog();
            //log.OperateTime = DateTime.Now;
            //log.OperateMessage = strModuleNo + " " + strOperateType;
            //IBLL.IBLL_Log logCtrl = BLLFactory.Factory.BLL_Log();
            //logCtrl.AddKeyOperationLog(log);
        }
        catch (Exception e)
        { }
    }

    #endregion

    #region 属性

    /// <summary>
    /// 设置模块代码，必须在子类中设置
    /// </summary>
    protected string ModuleNo
    {
        set { this._ModuleNo = value; }
        get { return this._ModuleNo; }
    }
    /// <summary>
    /// 设置 进入页面需要的操作类型
    /// </summary>
    protected string PageOperateType
    {
        set { this._OperateType = value; }
        get { return this._OperateType; }
    }
    /// <summary>
    /// 返回页面
    /// </summary>
    protected string ReturnUrl
    {
        get { return this._ReturnUrl; }
        set { this._ReturnUrl = value; }
    }
    /// <summary>
    /// 设置QueryCondition 加密串
    /// </summary>
    protected string QueryCondition
    {
        get { return this._QueryCondition; }
        set { this._QueryCondition = value; }
    }

    #endregion

    #region 保护方法
    /// <summary>
    /// 页面操作错误提示信息
    /// </summary>
    /// <param name="ErrMsg"></param>
    /// <param name="Url"></param>
    protected void PageError(string ErrMsg, string Url)
    {
        WebHint.ShowError(ErrMsg, Url);
    }

    /// <summary>
    /// 页面操作成功提示信息
    /// </summary>
    /// <param name="InfoMsg"></param>
    /// <param name="Url"></param>
    protected void PageInfo(string InfoMsg, string Url)
    {
        WebHint.ShowInfo(InfoMsg, Url);
    }

    /// <summary>
    /// 获取查询Model
    /// </summary>
    protected T GetQueryObject<T>() where T : new()
    {
        if (this._QueryCondition != "")
        {
            return StringUtility.ConvertStringToObject<T>(StringUtility.DeCompress(this._QueryCondition));
        }
        else
        {
            return default(T);
        }
    }

    /// <summary>
    /// 将给定的url加上script 实现页面跳转
    /// 针对button 的 onclintclick 
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    protected string GetURLScript(string str)
    {
        int index = str.IndexOf("?");
        //给url加returnUrl,值为当前页面的Url
        if (index != -1)
        {
            str += "&" + Constants.QUERYSTRING_RETURN_URL + "=" + Page.Request.RawUrl;
        }
        else
        {
            str += "?" + Constants.QUERYSTRING_RETURN_URL + "=" + Page.Request.RawUrl;
        }
        string strScript = "if(!this.disabled){window.location='" + str + "';} return false;";
        return strScript;
    }

    #endregion

}
